#include "Avalon/SignalHandling/ConnectionGroup.hpp"
#include "Avalon/Base/Algorithm.hpp"
#include "Avalon/SignalHandling/GroupConnection.hpp"

using namespace Avalon;
using namespace Avalon::SignalHandling;
using namespace boost;
using namespace boost::signals2;
using namespace std;

ConnectionGroup::ConnectionGroup() {}

ConnectionGroup::~ConnectionGroup() {
  DisconnectAll();
}

void ConnectionGroup::AddConnection(const connection& connection) {
  m_connections[NULL].push_back(new scoped_connection(connection));
}

void ConnectionGroup::AddConnection(
    const SignalHandling::GroupConnection& connection) {
  const vector<signals2::connection>& connections = connection.GetConnections();
  for(vector<signals2::connection>::const_iterator i = connections.begin();
      i != connections.end(); ++i) {
    AddConnection(*i);
  }
}

void ConnectionGroup::AddConnection(void* publisher,
    const connection& connection) {
  m_connections[publisher].push_back(new scoped_connection(connection));
}

void ConnectionGroup::AddConnection(void* publisher,
    const SignalHandling::GroupConnection& connection) {
  const vector<signals2::connection>& connections = connection.GetConnections();
  for(vector<signals2::connection>::const_iterator i = connections.begin();
      i != connections.end(); ++i) {
    AddConnection(publisher, *i);
  }
}

void ConnectionGroup::Disconnect(void* publisher) {
  map<void*, vector<scoped_connection*> >::iterator connectionIterator =
    m_connections.find(publisher);
  if(connectionIterator == m_connections.end()) {
    return;
  }
  vector<scoped_connection*>& connections = connectionIterator->second;
  Clear(connections);
  m_connections.erase(connectionIterator);
}

void ConnectionGroup::DisconnectAll() {
  for(map<void*, vector<scoped_connection*> >::iterator i =
      m_connections.begin(); i != m_connections.end(); ++i) {
    Clear(i->second);
  }
  m_connections.clear();
}
